package com.maya.medicalwastes;

import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.maya.medicalwastes.util.CustomProber;
import com.maya.medicalwastes.util.HexDump;
import com.maya.medicalwastes.util.UsbManagerUtil;
import com.tbossgroup.tbscale.TBScaleAidlInterface;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.Executors;

import butterknife.BindView;
import butterknife.ButterKnife;
import timing.ukulele.serialport.BuildConfig;
import timing.ukulele.serialport.driver.UsbSerialDriver;
import timing.ukulele.serialport.driver.UsbSerialPort;
import timing.ukulele.serialport.driver.UsbSerialProber;
import timing.ukulele.serialport.util.SerialInputOutputManager;


/**
 * @description 登录界面
 * @user gzl
 * @date 2017/4/25
 * @time 19:14
 */

public class ScaleActivity extends AppCompatActivity implements SerialInputOutputManager.Listener {

    @BindView(R.id.tv_title)
    TextView tv_title;
    @BindView(R.id.tvNetWeight)
    TextView tvNetWeight;

    private enum UsbPermission {Unknown, Requested, Granted, Denied}

    private static final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
    private static final int READ_WAIT_MILLIS = 2000;
    private BroadcastReceiver broadcastReceiver;
    private UsbPermission usbPermission = UsbPermission.Unknown;
    UsbDevice mDevices;
    private SerialInputOutputManager usbIoManager;
    private UsbSerialPort usbSerialPort;
    private boolean connected = false;
    private Handler mainLooper;
    private int deviceId, portNum, baudRate;
    private boolean withIoManager;
    //重量
    private String numb = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scale);
        ButterKnife.bind(this);
        mDevices = UsbManagerUtil.getDevices(this);
        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(INTENT_ACTION_GRANT_USB)) {
                    usbPermission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
                              ? UsbPermission.Granted : UsbPermission.Denied;
                    connect();
                }
            }
        };
        mainLooper = new Handler(Looper.getMainLooper());

    }


    private void connect() {
        UsbDevice device = null;
        UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        for (UsbDevice v : usbManager.getDeviceList().values())
            if (v.getDeviceId() == deviceId)
                device = v;
        if (device == null) {
            status("connection failed: device not found");
            return;
        }
        UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);
        if (driver == null) {
            driver = CustomProber.getCustomProber().probeDevice(device);
        }
        if (driver == null) {
            status("connection failed: no driver for device");
            return;
        }
        if (driver.getPorts().size() < portNum) {
            status("connection failed: not enough ports at device");
            return;
        }
        usbSerialPort = driver.getPorts().get(portNum);
        UsbDeviceConnection usbConnection = usbManager.openDevice(driver.getDevice());
        if (usbConnection == null && usbPermission == UsbPermission.Unknown && !usbManager.hasPermission(driver.getDevice())) {
            usbPermission = UsbPermission.Requested;
            PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(INTENT_ACTION_GRANT_USB), 0);
            usbManager.requestPermission(driver.getDevice(), usbPermissionIntent);
            return;
        }
        if (usbConnection == null) {
            if (!usbManager.hasPermission(driver.getDevice()))
                status("connection failed: permission denied");
            else
                status("connection failed: open failed");
            return;
        }

        try {
            usbSerialPort.open(usbConnection);
            usbSerialPort.setParameters(baudRate, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
            if (withIoManager) {
                usbIoManager = new SerialInputOutputManager(usbSerialPort, this);
                Executors.newSingleThreadExecutor().submit(usbIoManager);
            }
            status("connected");
            connected = true;
        } catch (Exception e) {
            status("connection failed: " + e.getMessage());
            disconnect();
        }
    }

    void status(String str) {
//        SpannableStringBuilder spn = new SpannableStringBuilder(str + '\n');
//        spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorStatusText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//        tv_weight.setText(spn);
        if (str.contains("connect")) {
            return;
        } else {
            tvNetWeight.setText(str);
        }


    }

    private void disconnect() {
        connected = false;
        if (usbIoManager != null)
            usbIoManager.stop();
        usbIoManager = null;
        try {
            if (usbSerialPort != null) {
                usbSerialPort.close();
            }
        } catch (IOException ignored) {
        }
        usbSerialPort = null;
    }

    @Override
    public void onNewData(byte[] data) {
        mainLooper.post(() -> {
            receive(data);
        });
    }

    private void receive(byte[] data) {
//        SpannableStringBuilder spn = new SpannableStringBuilder();
        //  spn.append("receive " + data.length + " bytes\n");

        if (data.length > 0) {
            String hexString = HexDump.toHexString(data);
            String assicString = HexDump.hexToAscii(hexString);
            numb = assicString.substring(7, assicString.length() - 4);
            tvNetWeight.setText(numb + "");
        }
    }

    @Override
    public void onRunError(Exception e) {
        mainLooper.post(() -> {
            status("connection lost: " + e.getMessage());
            disconnect();
        });
    }

}
